import platgo as pg
import numpy as np
from scipy.spatial.distance import cdist

"""
------------------------------- Reference --------------------------------
 D. Corne and J. Knowles, Techniques for highly multiobjective
 optimisation: some nondominated points are better than others,
 Proceedings of the 9th Annual Conference on Genetic and Evolutionary
 Computation, 2007, 773-780.
"""


class TSP(pg.Problem):

    def __init__(self, D: int = 30, R: np.ndarray = None):
        """
        :param D: dimension of decs
        :param R: Locations of points
        """
        # TODO add file operation, check borders
        self.name = "TSP"
        self.borders = []
        self.type['single'], self.type['permutation'], self.type['large'] = [True] * 3
        self.M = 1
        self.D = D
        if R is None:
            self.R = np.random.random((self.D, 2))
        else:
            self.R = R
            self.D = R.shape[0]
        self.C = cdist(self.R, self.R)
        super().__init__()

    def cal_obj(self, pop: pg.Population) -> None:
        pop.objv = np.zeros((pop.decs.shape[0], 1))
        for i in range(len(pop.decs)):
            for j in range(self.D-1):
                pop.objv[i] = pop.objv[i] + self.C[pop.decs[i][j]][pop.decs[i][j+1]]
            pop.objv[i] = self.C[pop.decs[i][-1]][pop.decs[i][0]] + pop.objv[i]

    def get_optimal(self) -> np.ndarray:
        pass


if __name__ == "__main__":
    a = np.array([[0.814723686393179, 0.706046088019609],
[0.905791937075619,	0.0318328463774207],
[0.126986816293506,	0.276922984960890],
[0.913375856139019,	0.0461713906311539],
[0.632359246225410,	0.0971317812358475],
[0.0975404049994095, 0.823457828327293],
[0.278498218867048, 0.694828622975817],
[0.546881519204984,	0.317099480060861],
[0.957506835434298,	0.950222048838355],
[0.964888535199277,	0.0344460805029088],
[0.157613081677548,	0.438744359656398],
[0.970592781760616,	0.381558457093008],
[0.957166948242946,	0.765516788149002],
[0.485375648722841,	0.795199901137063],
[0.800280468888800,	0.186872604554379],
[0.141886338627215,	0.489764395788231],
[0.421761282626275,	0.445586200710900],
[0.915735525189067,	0.646313010111265],
[0.792207329559554,	0.709364830858073],
[0.959492426392903,	0.754686681982361],
[0.655740699156587,	0.276025076998578],
[0.0357116785741896, 0.679702676853675],
[0.849129305868777,	0.655098003973841],
[0.933993247757551,	0.162611735194631],
[0.678735154857774,	0.118997681558377],
[0.757740130578333,	0.498364051982143],
[0.743132468124916,	0.959743958516081],
[0.392227019534168,	0.340385726666133],
[0.655477890177557,	0.585267750979777],
[0.171186687811562, 0.223811939491137]])
    problem = TSP(R=a)
    pop = pg.Population(decs=np.array([[9,8,7,6,5,4,3,2,1,0,19,18,17,16,15,14,13,12,11,10,29,28,27,26,25,24,23,22,21,20],
                                       [29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0]]))
    problem.cal_obj(pop)
    print(pop.objv)